//
//  XCDebug.h
//  Pods
//
//  Created by xiongwei on 2017/1/7.
//
//

#import <Foundation/Foundation.h>

#if defined(DEBUG) || defined(BF_DEBUG)

/**
 * Assertions that only fire when DEBUG is defined.
 *
 * An assertion is like a programmatic breakpoint. Use it for sanity checks to save headache while
 * writing your code.
 */
#import <TargetConditionals.h>

#if defined __cplusplus
extern "C" {
#endif

/**
 * 判断是否正在debug
 */
int XCIsInDebugger(void);

/**
 * 充值日志级别
 */
void XCResetMaxLogLevel(void);

#if defined __cplusplus
}
#endif

#if TARGET_IPHONE_SIMULATOR
// We leave the __asm__ in this macro so that when a break occurs, we don't have to step out of
// a "breakInDebugger" function.
#define XCASSERT(xx) { if (!(xx)) { XCLog(@"XCASSERT failed: %s", #xx); \
if (XCDebugAssertionsShouldBreak && XCIsInDebugger()) { __asm__("int $3\n" : : ); } } \
} ((void)0)
#else
#define XCASSERT(xx) { if (!(xx)) { XCLog(@"XCASSERT failed: %s", #xx); \
if (BFDebugAssertionsShouldBreak && XCIsInDebugger()) { raise(SIGTRAP); } } \
} ((void)0)
#endif // #if TARGET_IPHONE_SIMULATOR

#else
#define XCASSERT(xx) ((void)0)
#endif // #if defined(DEBUG) || defined(BF_DEBUG)


#define XCLOGLEVEL_INFO     5
#define XCLOGLEVEL_WARNING  3
#define XCLOGLEVEL_ERROR    1

/**
 * 日志最高级别，默认为XCLOGLEVEL_WARNING
 */
extern NSUInteger XCMaxLogLevel;

/**
 * 是否需要在debug模式下ASSERT失败时自动断点
 *
 * 默认为YES.
 */
extern BOOL XCDebugAssertionsShouldBreak;

/**
 * XCLog
 */
#if defined(DEBUG) || defined(XC_DEBUG)
//#define BFLog(xx, ...)  NSLog(@"%s(line:%d): " xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
// ios10 xcode8
#define XCLog(xx, ...)  fprintf(stderr, "XCLog\t %s(line:%d): %s\n", __PRETTY_FUNCTION__, __LINE__, [[NSString stringWithFormat:xx, ##__VA_ARGS__] UTF8String])
#else
#define XCLog(xx, ...)  ((void)0)
#endif // #if defined(DEBUG) || defined(BF_DEBUG)

/**
 * 输出函数名称
 */
#define XCPRINTMETHODNAME() XCLog(@"%s", __PRETTY_FUNCTION__)

#if defined(DEBUG) || defined(XC_DEBUG)
/**
 * Only writes to the log if condition is satisified.
 *
 * This macro powers the level-based loggers. It can also be used for conditionally enabling
 * families of logs.
 */
#define XCCONDITIONLOG(condition, xx, ...) { if ((condition)) { BFLog(xx, ##__VA_ARGS__); } \
} ((void)0)
#else
#define XCCONDITIONLOG(condition, xx, ...) ((void)0)
#endif // #if defined(DEBUG) || defined(BF_DEBUG)


/**
 * 输出日志，条件： XCMaxLogLevel >= XCLOGLEVEL_ERROR.
 */
#define XCERROR(xx, ...)  XCCONDITIONLOG((XCLOGLEVEL_ERROR <= XCMaxLogLevel), xx, ##__VA_ARGS__)

/**
 * 输出日志，条件： XCMaxLogLevel >= XCLOGLEVEL_WARNING.
 */
#define XCWARNING(xx, ...)  XCCONDITIONLOG((XCLOGLEVEL_WARNING <= XCMaxLogLevel), \
xx, ##__VA_ARGS__)

/**
 * 输出日志，条件： XCMaxLogLevel >= XCLOGLEVEL_INFO.
 */
#define XCINFO(xx, ...)  XCCONDITIONLOG((XCLOGLEVEL_INFO <= XCMaxLogLevel), xx, ##__VA_ARGS__)

/**@}*///
